﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace Aribaccio
{
    /// <summary>
    /// 树形节点
    /// </summary>
    public partial class TreeNode<T> : ObservableModel where T : class, new()
    {
        /// <summary>
        /// 编号
        /// </summary>
        public int ID { get; set; }

        /// <summary>
        /// 节点层级
        /// </summary>
        [ObservableProperty]
        protected int level = 0;

        /// <summary>
        /// 节点名称
        /// </summary>
        [ObservableProperty]
        protected string name = string.Empty;

        /// <summary>
        /// 是否选中
        /// </summary>
        [ObservableProperty]
        protected bool isChecked = false;

        /// <summary>
        /// 是否有效
        /// </summary>
        [ObservableProperty]
        protected bool isEnabled = false;

        /// <summary>
        /// 是否展开
        /// </summary>
        [ObservableProperty]
        protected bool isExpanded = false;

        /// <summary>
        /// 源数据
        /// </summary>
        public T SourceData { get; set; }

        /// <summary>
        /// 父节点
        /// </summary>
        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(IsExistsParent))]
        protected TreeNode<T>? parent;

        /// <summary>
        /// 子节点集合
        /// </summary>
        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(IsExistsChilds))]
        protected ObservableCollection<TreeNode<T>>? childs;

        /// <summary>
        /// 是否存在父节点
        /// </summary>
        public bool IsExistsParent => this.Parent != null;

        /// <summary>
        /// 是否存在子节点
        /// </summary>
        public bool IsExistsChilds => this.Childs != null && this.Childs.Count > 0;

        /// <summary>
        /// 构造函数
        /// </summary>
        public TreeNode(int argID, string argName, T argSourceData, bool argIsChecked = false, bool argIsEnabled = false, bool argIsExpanded = false, TreeNode<T>? argParent = null)
        {
            this.ID = argID;
            this.Name = argName;
            this.SourceData = argSourceData;
            this.IsChecked = argIsChecked;
            this.IsEnabled = argIsEnabled;
            this.IsExpanded = argIsExpanded;
            if (argParent != null)
            {
                this.Parent = argParent;
                this.Level = argParent.Level + 1;
            }
        }

        /// <summary>
        /// 添加子节点
        /// </summary>
        public void AddChild(TreeNode<T> argTreeNode)
        {
            if (argTreeNode == null) return;
            if (this.Childs == null) this.Childs = new ObservableCollection<TreeNode<T>>();
            this.Childs.Add(argTreeNode);
        }

        /// <summary>
        /// 添加子节点集合
        /// </summary>
        public void AddChilds(List<TreeNode<T>> argTreeNodes)
        {
            if (argTreeNodes == null || argTreeNodes.Count <= 0) return;
            if (this.Childs == null)
            {
                this.Childs = new ObservableCollection<TreeNode<T>>(argTreeNodes);
            }
            else
            {
                foreach (TreeNode<T> argTreeNode in argTreeNodes)
                {
                    if (argTreeNode == null) continue;
                    this.Childs.Add(argTreeNode);
                }
            }
        }

        /// <summary>
        /// 选中状态改变事件
        /// </summary>
        [RelayCommand]
        public void ExecuteCheckedChanged()
        {
            //刷新子节点选中状态
            this.RefreshCheckedToChild(this, this.IsChecked);
            //刷新父节点选中状态
            this.RefreshCheckedToParent(this.Parent, this.IsChecked);
        }

        /// <summary>
        /// 刷新子节点选中状态
        /// </summary>
        /// <param name="argIsChecked"></param>
        public void RefreshCheckedToChild(TreeNode<T> argTreeNode, bool argIsChecked)
        {
            if (argTreeNode.IsChecked != argIsChecked)
            {
                argTreeNode.IsChecked = argIsChecked;
            }

            if (argTreeNode.Childs == null || argTreeNode.Childs.Count <= 0) return;
            foreach (var childNode in argTreeNode.Childs)
            {
                if (childNode == null) continue;
                //递归循环子节点
                childNode.RefreshCheckedToChild(childNode, argIsChecked);
            }
        }

        /// <summary>
        /// 刷新父节点选中状态
        /// </summary>
        /// <param name="argIsChecked"></param>
        public void RefreshCheckedToParent(TreeNode<T>? argTreeNodeParent, bool argIsChecked)
        {
            if (argTreeNodeParent == null) return;
            if (argTreeNodeParent.Childs != null && argTreeNodeParent.Childs.Count > 1)
            {
                if (argTreeNodeParent.Childs.Where(v => v.IsChecked).Count() > 0)
                {
                    if (!argTreeNodeParent.IsChecked) argTreeNodeParent.IsChecked = true;
                }
                else
                {
                    if (argTreeNodeParent.IsChecked) argTreeNodeParent.IsChecked = false;
                }
            }
            else
            {
                argTreeNodeParent.IsChecked = argIsChecked;
            }
            //递归父节点
            argTreeNodeParent.RefreshCheckedToParent(argTreeNodeParent.Parent, argIsChecked);

        }
    }
}
